#!/usr/bin/php
<?php

/*
 * PHP文档：
 *     函数
 *         函数名
 *         版本支持
 *         函数简介
 *         函数原型
 *         函数说明
 *         函数参数
 *         函数返回值
 *         更新日志
 *         范例
 *         相关函数
 *     类
 *     常量
 *     方法
 */

set_exception_handler(function($e){
    fprintf(STDERR, "%s%s", $e->getMessage(), PHP_EOL);
    exit($e->getCode());
});

class manual
{
    const BODY_REPLACE = "{Kyo Body}".PHP_EOL;
    const TS = '    ';

    private $manual_dir;
    private $dir;
    private $dp;

    public function __construct($manual_path, $dst_path = null)
    {
        if (!is_dir($manual_path)) {
            throw new Exception("PHP Maunal目录指定错误!");
        }

        if ($dst_path == null)
            $dst_path = $manual_path.DIRECTORY_SEPARATOR."vim";

        if (!file_exists($dst_path) && !mkdir($dst_path)) {
            throw new Exception("目标路径创建失败!");
        }
        $this->dir = $dst_path;
        $this->manual_dir = $manual_path;

        $this->dp = opendir($manual_path);
        if (!$this->dp) {
            throw new Exception("PHP Manual目录打开失败!");
        }
    }

    public function write($file, $content)
    {
        echo $content;
        file_put_contents($this->dir.DIRECTORY_SEPARATOR.$file, $content);
    }

    static public function getdelim($ch = '=', $num = 80)
    {
        for ($i = 0, $s = ""; $i < $num; ++$i) {
            $s .= $ch;
        }

        $s .= PHP_EOL;

        return $s;
    }


    static public function menu($s)
    {
        preg_match_all('/class="(prev|next|up)".*html">([^<>]+)<\/a/m',
            $s, $m);

        if (count($m[2]) == 0)
            return "";

        $s =  "|Manual|";

        $index = array_search("up", $m[1]);
        if ($index !== FALSE)
            $s .= ' -> '.str_replace(" ", "_", $m[2][$index]);

        $s .= PHP_EOL;

        $index = array_search("prev", $m[1]);
        if ($index !== FALSE)
            $s .= 'Prev: |'.$m[2][$index].'|'.PHP_EOL;

        $s .= self::getdelim();

        $s .= manual::BODY_REPLACE;

        $index = array_search("next", $m[1]);
        if ($index !== FALSE) {
            $s .= self::getdelim();
            $s .= 'Next |'.$m[2][$index].'|'.PHP_EOL;
        }

        $s .= PHP_EOL."vim:ft=help:";

        return $s;
    }

    static public function type($file)
    {
        if (!strncmp($file, "function.", 9))
            return "func";
    }

    static public function get_func($s)
    {
        $body = "";
        // 函数名
        preg_match_all('/<h1 class="refname">([^<>]+)<\/h1>/', $s, $m);
        foreach ($m[1] as $name) {
            $body .= $name.PHP_EOL;
        }
        $body .= PHP_EOL;

        // 版本支持和函数简介
        preg_match_all('/class="verinfo">([^<>]+)<\/p><p[^>]*>(.*)<\/p>/', $s, $m);
        $body .= manual::TS.html_entity_decode($m[1][0]).PHP_EOL;
        $body .= manual::TS.html_entity_decode(strip_tags($m[2][0])).PHP_EOL;
        htmlentities

        // 函数原型
        preg_match_all('/<h3 class="title">[^<>]+<\/h3>(.*)/', $s, $m);
        print_r($m);

        return $body;

        // 函数说明
        // 函数参数
        // 函数返回值
        // 更新日志
        // 范例
        // 相关函数

        return "";

    }

    static public function read($path, $type)
    {
        echo $path, PHP_EOL;
        $s = file_get_contents($path);
        if ($s == FALSE)
            return null;

        //导航内容
        $header = self::menu($s);

        //中间内容
        $call = "get_".$type;
        $body = self::$call($s);

        return str_replace(manual::BODY_REPLACE, $body, $header);
    }

    public function work()
    {
        while (($file = readdir($this->dp)) !== FALSE) {
            if ($file === '.' || $file === '..')
                continue;
            $this->write($file, self::read(
                    $this->manual_dir.DIRECTORY_SEPARATOR.$file,
                    self::type($file)
                ));
            break;
        }
    }
}


function main($argc, & $argv)
{
/*
 *     if ($argc < 3 || !file_exists($argv[1])) {
 *         throw new Exception("请指定PHP Manual目录路径和生成路径!");
 *     }
 *
 *     $m = new manual($argv[1], $argv[2]);
 */
    $m = new manual("/kyo/res/function/", "/kyo/res/vim");
    $m->work();

    return 0;
}

exit(main($argc, $argv));

